package nil.ed.lazy.base.currency;

/**
 * 人民币单位，不处理溢出
 * @author delin10
 * @since 2020/8/10
 **/
public enum RMBUnit {
    /**
     * 广告货币单位转换
     */
    YUAN(1, "元") {
        @Override
        public double toYuan(double sourceAmount) {
            return sourceAmount;
        }

        @Override
        public double toJiao(double sourceAmount) {
            return sourceAmount * YUAN_TO_JIAO;
        }

        @Override
        public double toFen(double sourceAmount) {
            return sourceAmount * YUAN_TO_JIAO * JIAO_TO_FEN;
        }

        @Override
        public double toSi(double sourceAmount) {
            return sourceAmount * YUAN_TO_JIAO * JIAO_TO_FEN * FEN_TO_SI;
        }

        @Override
        public double convert(double sourceAmount, RMBUnit sourceUnit) {
            return sourceUnit.toYuan(sourceAmount);
        }
    }, JIAO(2, "角") {
        @Override
        public double toYuan(double sourceAmount) {
            return sourceAmount / YUAN_TO_JIAO;
        }

        @Override
        public double toJiao(double sourceAmount) {
            return sourceAmount;
        }

        @Override
        public double toFen(double sourceAmount) {
            return sourceAmount * JIAO_TO_FEN;
        }

        @Override
        public double toSi(double sourceAmount) {
            return sourceAmount * JIAO_TO_FEN * FEN_TO_SI;
        }

        @Override
        public double convert(double sourceAmount, RMBUnit sourceUnit) {
            return sourceUnit.toJiao(sourceAmount);
        }
    }, FEN(3, "分") {
        @Override
        public double toYuan(double sourceAmount) {
            return sourceAmount / JIAO_TO_FEN / YUAN_TO_JIAO;
        }

        @Override
        public double toJiao(double sourceAmount) {
            return sourceAmount / JIAO_TO_FEN;
        }

        @Override
        public double toFen(double sourceAmount) {
            return sourceAmount;
        }

        @Override
        public double toSi(double sourceAmount) {
            return sourceAmount * FEN_TO_SI;
        }

        @Override
        public double convert(double sourceAmount, RMBUnit sourceUnit) {
            return sourceUnit.toFen(sourceAmount);
        }
    }, SI(4, "丝") {
        @Override
        public double toYuan(double sourceAmount) {
            return sourceAmount / FEN_TO_SI / JIAO_TO_FEN / YUAN_TO_JIAO;
        }

        @Override
        public double toJiao(double sourceAmount) {
            return sourceAmount / FEN_TO_SI / JIAO_TO_FEN;
        }

        @Override
        public double toFen(double sourceAmount) {
            return sourceAmount / FEN_TO_SI;
        }

        @Override
        public double toSi(double sourceAmount) {
            return sourceAmount;
        }

        @Override
        public double convert(double sourceAmount, RMBUnit sourceUnit) {
            return sourceUnit.toSi(sourceAmount);
        }
    };

    private final int code;
    private final String desc;

    /**
     * 元 -> 角
     */
    static final double YUAN_TO_JIAO = 10D;
    /**
     * 角 -> 分
     */
    static final double JIAO_TO_FEN = 10D;
    /**
     * 丝
     */
    static final double FEN_TO_SI = 1000D;

    RMBUnit(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public double convert(double sourceAmount, RMBUnit sourceUnit) {
        throw new AbstractMethodError();
    }

    public double toYuan(double sourceAmount) {
        throw new AbstractMethodError();
    }

    public double toJiao(double sourceAmount) {
        throw new AbstractMethodError();
    }

    public double toFen(double sourceAmount) {
        throw new AbstractMethodError();
    }

    public double toSi(double sourceAmount) {
        throw new AbstractMethodError();
    }

    public int getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }

}
